<chapter xml:id="string_utils.h">
<title><tt>__vic/string_utils.h</tt></title>

<p>Различные утилиты для работы со строками.</p>


<chapter xml:id="trim">
<title>Набор функций <tt>trim</tt></title>

<code-block lang="C++"><![CDATA[
char *trim(char *str);
char *trim_front(char *str);
char *trim_back(char *str);
char *trim(char *str, char ch);
char *trim_front(char *str, char ch);
char *trim_back(char *str, char ch);
char *trim(char *str, const char *set);
char *trim_front(char *str, const char *set);
char *trim_back(char *str, const char *set);

std::string &trim(std::string &str);
std::string &trim_front(std::string &str);
std::string &trim_back(std::string &str);
std::string &trim(std::string &str, char ch);
std::string &trim_front(std::string &str, char ch);
std::string &trim_back(std::string &str, char ch);
std::string &trim(std::string &str, const char *set);
std::string &trim_front(std::string &str, const char *set);
std::string &trim_back(std::string &str, const char *set);

std::string trimmed(const std::string &str);
std::string trimmed_front(const std::string &str);
std::string trimmed_back(const std::string &str);
std::string trimmed(const std::string &str, char ch);
std::string trimmed_front(const std::string &str, char ch);
std::string trimmed_back(const std::string &str, char ch);
std::string trimmed(const std::string &str, const char *set);
std::string trimmed_front(const std::string &str, const char *set);
std::string trimmed_back(const std::string &str, const char *set);
]]></code-block>

<p>Набор функций, обрезающих нежелательные символы по краям строки. Обрезаемые
символы можно задавать. Задать можно как одиночный символ <tt>ch</tt>, так и
набор <tt>set</tt>. Если набор не задан, то подразумеваются все пробельные
ASCII-символы. Используются следующие правила именования:</p>
<list style="bulleted">
    <item><tt>trim</tt> – обрезает строку с обоих концов,</item>
    <item><tt>trim_front</tt> – обрезает строку в начале,</item>
    <item><tt>trim_back</tt> – обрезает строку в конце.</item>
</list>

<p>Функции <tt>trim</tt> модифицируют переданную строку и возвращают указатель
или ссылку на неё. Если это по каким-то причинам нежелательно, то следует
использовать набор функций <tt>trimmed</tt>.</p>
<list style="bulleted">
    <item><tt>trimmed</tt> – возвращает обрезанную строку в качестве выходного
        значения, не модифицируя входной параметр.</item>
</list>

<p>Реализация функций <tt>trim</tt> выполнена с расчётом, что у строки может
не быть символов, подлежащих обрезанию. В подобных случаях никаких модификаций
не производится, и функция возвращает управление сразу после проверки. С точки
зрения эффективности, затраты на такие вызовы минимальны.</p>

<p>Все значения <tt>nullptr</tt> воспринимаются как пустая строка.</p>

<section><title>Примеры</title>
<code-block lang="C++">
char st1[] = "\t value    \n";

// CHOICE:
__vic::trim(st1);       // result: "value"
__vic::trim_front(st1); // result: "value    \n"
__vic::trim_back(st1);  // result: "\t value"

std::string st2("...value123");

// CHOICE:
// trim dot chars
__vic::trim_front(st1, '.');        // result: "value123"
// trim all digits
__vic::trim_back(st1, "123456789"); // result: "...value"
</code-block>
</section>

</chapter>


<chapter xml:id="sift">
<title><tt>sift()</tt></title>

<code-block lang="C++"><![CDATA[
char *sift(char *str, const char *trash_chars);
std::string &sift(std::string &str, const char *trash_chars);
]]></code-block>

<p>Удаляет из строки все символы из указанного набора. Все значения
<tt>nullptr</tt> воспринимаются как пустая строка.</p>

<section><title>Пример</title>
<code-block lang="C++">
char st[] = "..ab.c..d.e.";
__vic::sift(st, ".");
assert(std::strcmp(st, "abcde") == 0);
</code-block>
</section>

</chapter>


<chapter xml:id="sift_if">
<title><tt>sift_if()</tt></title>

<code-block lang="C++"><![CDATA[
template<class Pred>
char *sift(char *str, Pred pred);
template<class Pred>
std::string &sift(std::string &str, Pred pred);
]]></code-block>

<p>Удаляет из строки все символы, удовлетворяющие предикату <tt>pred</tt>.
Все значения <tt>nullptr</tt> воспринимаются как пустая строка.</p>

</chapter>


<chapter xml:id="pad_front">
<title><tt>pad_front()</tt></title>

<code-block lang="C++"><![CDATA[
std::string &pad_front(std::string &str, size_t size, char pad_ch = ' ');
char *pad_front(char *str, size_t size, char pad_ch = ' ');
]]></code-block>

<p>Дополняет строку до длины <tt>size</tt> в начале символами
<tt>pad_ch</tt>. Ничего не происходит, если строка уже имеет длину
<tt>size</tt> или большую, либо указатель - null. Возвращает <tt>str</tt>.</p>

</chapter>


<chapter xml:id="pad_back">
<title><tt>pad_back()</tt></title>

<code-block lang="C++"><![CDATA[
std::string &pad_back(std::string &str, size_t size, char pad_ch = ' ');
char *pad_back(char *str, size_t size, char pad_ch = ' ');
]]></code-block>

<p>Дополняет строку до длины <tt>size</tt> в конце символами
<tt>pad_ch</tt>. Ничего не происходит, если строка уже имеет длину
<tt>size</tt> или большую, либо указатель - null. Возвращает <tt>str</tt>.</p>

</chapter>


<chapter xml:id="starts_with">
<title><tt>starts_with()</tt></title>

<code-block lang="C++"><![CDATA[
bool starts_with(const char *s, char pref);
bool starts_with(const char *s, const char *pref);
bool starts_with(const char *s, const char *pref, size_t pref_len);

#if __cpp_lib_string_view // C++17
bool starts_with(std::string_view s, char pref);
bool starts_with(std::string_view s, std::string_view pref);
bool starts_with(std::string_view s, const char *pref);
#else // until C++17
bool starts_with(const std::string &s, char pref);
bool starts_with(const std::string &s, const char *pref);
bool starts_with(const std::string &s, const std::string &pref);
bool starts_with(const std::string &s, const char *pref, size_t pref_len);
#endif

bool starts_with(const char *s, size_t s_len, char pref);
bool starts_with(const char *s, size_t s_len, const char *pref);
bool starts_with(const char *s, size_t s_len, const char *pref, size_t pref_len);
]]></code-block>

<p>Возвращает <tt>true</tt>, если строка <tt>s</tt> начинается с указанного
префикса.</p>

</chapter>


<chapter xml:id="ends_with">
<title><tt>ends_with()</tt></title>

<code-block lang="C++"><![CDATA[
#if __cpp_lib_string_view // C++17
bool ends_with(std::string_view s, char suff);
bool ends_with(std::string_view s, std::string_view suff);
#else // until C++17
bool ends_with(const char *s, char suff);
bool ends_with(const char *s, const char *suff);
bool ends_with(const char *s, const char *suff, size_t suff_len);
bool ends_with(const char *s, size_t s_len, const char *suff);

bool ends_with(const std::string &s, char suff);
bool ends_with(const std::string &s, const char *suff);
bool ends_with(const std::string &s, const std::string &suff);
bool ends_with(const std::string &s, const char *suff, size_t suff_len);
#endif

bool ends_with(const char *s, size_t s_len, char suff);
bool ends_with(const char *s, size_t s_len, const char *suff, size_t suff_len);
]]></code-block>

<p>Возвращает <tt>true</tt>, если строка <tt>s</tt> оканчивается указанным
суффиксом.</p>

</chapter>


</chapter>
